home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Copyright 1993, 1994, Cornell University
-
- Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose
- and without fee, provided that these copyright and permission notices appear on all copies and
- supporting documentation, the name of Cornell not be used in advertising or publicity pertaining
- to distribution of the program without specific prior permission, notice be given in supporting
- documentation that copying and distribution is by permission of Cornell. CORNELL MAKES NO
- REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED. By way of example, but not limitation,
- CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
- PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS,
- TRADEMARKS, OR OTHER RIGHTS. Cornell shall not be held liable for any liability with respect to
- any claim by the user or any other party arising from use of the program.
-
- This material is partially based on work sponsored by the National Science Foundation under Cooperative
- Agreement No. NCR-9318337. The government has certain rights in this material.
-
- */
-
-
-
- #include <stdio.h>
- #include <varargs.h>
- #include <signal.h>
- #include <errno.h>
- #include <malloc.h>
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <sys/time.h>
-
- #ifndef LINUX
- #include <sys/socketvar.h>
- #include <net/route.h>
- #endif
-
- #include <net/if.h>
- #include <netinet/in.h>
-
- #include "reflect.h"
- #include "refmon.h"
- #include "globals.h"
-
- #define MAXIF 20 /* Maximum number of interfaces expected */
-
- #if BSD > 43
- #define socksize(x) ((struct sockaddr *)x)->sa_len
- #else
- #define socksize(x) sizeof *(x)
- #endif
-
- void proc_sig()
- {
- my_perror("Kill Signal received\n");
- exit(1);
- }
-
-
- void do_timer()
- {
- static short refrefkcnt = 0;
- static short vatinterval = 0;
- static short timeinterval = 0;
- client *ctmp,*ctmp1;
- vat_client *mtmp,*mtmp1;
- struct in_addr in;
- struct timeval tp;
- struct timezone tzp;
- float elapsed;
- short cnt,cnt1;
- char *tmp;
-
- tick_cnt++;
- gettimeofday(&tp, &tzp);
-
- #ifndef DONTLOGPKTS
- if ((++timeinterval >= 10) && (chead != NULL))
- {
- tmp = ctime(&tp.tv_sec);
- tmp[24] = ' ';
- dolog("Time: %s Pkts in %ld Pkts out %ld kbits/sec in %d kbits/sec out %d\n",
- tmp,pkts_in,pkts_out,(short) ((8 * bytes_in)/10240),(short) ((8 * bytes_out)/10240));
- timeinterval = 0;
- pkts_in = pkts_out = bytes_in = bytes_out = 0;
- }
- #endif
-
- /* run through the client list */
-
- ctmp = chead;
- while (ctmp != NULL)
- {
- ctmp->clnt_stimer++;
- ctmp->clnt_caploop++;
-
- /* check for cap rate violations */
-
- if ((ctmp->clnt_flags & (CLIENT | NV_UCAST)) && (ctmp->clnt_caploop == TRATE) && (ctmp->clnt_bytecnt != 0))
- {
- elapsed = tp.tv_sec - ctmp->clnt_tp.tv_sec;
- elapsed += (tp.tv_usec/1000000.) - (ctmp->clnt_tp.tv_usec/1000000.);
-
- /*
- printf("transmission rate is %f bytes per sec cap is %d elapsed is %f\n",
- (float) ctmp->clnt_bytecnt/elapsed,cap,elapsed);
- */
-
- if (ctmp->clnt_bytecnt/elapsed > cap)
- {
- ctmp1 = ctmp;
- ctmp = ctmp->clnt_nptr;
- dolog("client %s is being deleted due to cap rate %f exceeding limit %d\n",
- ctmp1->clnt_config.name,ctmp1->clnt_bytecnt/elapsed,cap);
-
- if (ctmp->clnt_flags & CLIENT)
- write_msg(&ctmp1->clnt_addr,kMessageType1,cap_buf);
- tmp_deny(ctmp1->clnt_addr.addr,hold_down);
- hold_down_client(ctmp1);
- continue;
- }
-
- ctmp->clnt_bytecnt = 0;
- ctmp->clnt_caploop = 0;
- ctmp->clnt_tp.tv_sec = tp.tv_sec;
- ctmp->clnt_tp.tv_usec = tp.tv_usec;
- }
-
- /* next check for hold down expirations */
-
- if (ctmp->clnt_flags & HOLD_DOWN)
- {
- if (ctmp->clnt_hdloop++ > HRATE)
- {
- ctmp1 = ctmp;
- ctmp = ctmp->clnt_nptr;
- dolog("client %s hold down has expired and is being deleted\n",ctmp1->clnt_config.name);
- delete_client(ctmp1);
- continue;
- }
- }
-
- /* delete any NV, BCC_CLIENT, or regular clients that have timed out */
-
- if ((ctmp->clnt_flags & (CLIENT | NV_UCLIENT | NV_MCLIENT | BCC_CLIENT)) != 0)
- if ((ctmp->clnt_rtimer++ > TIMEOUT) && ((ctmp->clnt_flags & HOLD_DOWN) == 0))
- {
- ctmp1 = ctmp;
- ctmp = ctmp->clnt_nptr;
- if (ctmp1->clnt_flags & CLIENT)
- {
- dolog("client timeout -- holding down\n");
- hold_down_client(ctmp1);
- }
- else
- {
- if (ctmp1->clnt_flags & BCC_CLIENT)
- dolog("BCC client timeout -- deleting\n");
- else
- {
- /* if this nv client is also a vat client, update the vat seq # */
- if ((mtmp = find_vat_client(ctmp1->clnt_addr.addr)) != NULL)
- mtmp->mvn_ocp_seq = ctmp1->clnt_ocp_cnt + ctmp1->clnt_seq + 1;
- dolog("NV client timeout -- deleting\n");
- }
- delete_client(ctmp1);
- }
- continue;
- }
-
- /* delete any clients that originated from another reflector that have timed out */
-
- if ((ctmp->clnt_flags & (BCC_ORIGIN | REF1_ORIGIN | REF2_ORIGIN | REF3_ORIGIN)) != 0)
- if (ctmp->clnt_rtimer++ > (2*TIMEOUT))
- {
- ctmp1 = ctmp;
- ctmp = ctmp->clnt_nptr;
- if (ctmp1->clnt_flags & BCC_ORIGIN)
- dolog("BCC client's client timeout -- deleting\n");
- else
- dolog("REF client's client timeout -- deleting\n");
- delete_client(ctmp1);
- continue;
- }
-
-
- /* send OCP to our CUSM clients for our NV clients */
-
- if (ctmp->clnt_flags & (NV_UCLIENT | NV_MCLIENT))
- if (ctmp->clnt_ntimer++ > NV_OCP_TIMER)
- {
- send_nv_ocp(ctmp);
- ctmp->clnt_ntimer = 0;
- }
-
- ctmp = ctmp->clnt_nptr;
- }
-
- /* send keep alive packets to any BCC servers that we have */
-
- if (++refrefkcnt > KALIVE)
- {
- refrefkcnt = 0;
- open_bcc_servers();
- open_ucast_ref();
- }
-
-
- vatinterval++;
- if (vatinterval == 11)
- vatinterval = 0;
-
- mtmp = mhead;
- while (mtmp != NULL)
- {
- if (mtmp->mvn_rtimer++ > 200)
- {
- in.s_addr = mtmp->mvn_addr.addr;
- dolog("Deleting Maven client at %s\n", inet_ntoa(in));
-
- vat_client_cnt--;
-
- if (mtmp == mhead)
- {
- mhead = mtmp->mvn_nptr;
- mtmp1 = mtmp;
- mtmp = mtmp->mvn_nptr;
- free(mtmp1);
- }
- else
- {
- mtmp1 = mhead;
- while (mtmp1->mvn_nptr != mtmp)
- mtmp1 = mtmp1->mvn_nptr;
- mtmp1->mvn_nptr = mtmp->mvn_nptr;
- mtmp1 = mtmp;
- mtmp = mtmp->mvn_nptr;
- free(mtmp1);
- }
- continue;
- }
- else
- mtmp = mtmp->mvn_nptr;
- }
-
-
- mtmp = mhead;
- while (mtmp != NULL)
- {
- /* send OCP to our CUSM clients for our VAT-non NV clients */
-
- if ((find_client(mtmp->mvn_addr.addr) == NULL) && (vatinterval == 10))
- {
- if ((mtmp->mvn_spoke != 0) && ((tick_cnt - mtmp->mvn_spoke) < VAT_SPEAKER_INTERVAL))
- send_vat_ocp(mtmp);
- }
-
- mtmp = mtmp->mvn_nptr;
- }
-
- if (vatinterval == 10)
- send_vat_idlist();
-
- for (cnt=0; cnt<MAXCLIENT; cnt++)
- if (tmp_deny_list[cnt] != 0)
- if ((tmp_deny_wait[cnt] -= 1) == 0)
- tmp_deny_list[cnt] = 0;
-
- for (cnt=0; cnt<send_to_nv_cnt; cnt++)
- if (send_to_nv_timer[cnt]++ > TIMEOUT)
- {
- for (cnt1=cnt; cnt1<send_to_nv_cnt-1; cnt1++)
- {
- send_to_nv_list[cnt1] = send_to_nv_list[cnt1+1];
- send_to_nv_timer[cnt1] = send_to_nv_timer[cnt1+1];
- }
- send_to_nv_cnt--;
- }
- }
-
- void my_perror(mesg)
- char *mesg;
- {
- extern char *sys_errlist[];
- extern int errno;
-
- dolog("%s : %s: FATAL ERROR: EXITING", mesg, sys_errlist[errno]);
- printf("%s : %s: FATAL ERROR: EXITING", mesg, sys_errlist[errno]);
- exit(1);
- }
-
- dolog(va_alist)
- va_dcl
- {
- static int line_cnt = 0;
- char *fmt;
- va_list args;
-
- if (log_limit == 0)
- return;
-
- if (log_limit != -1)
- {
- if (line_cnt++ > log_limit)
- {
- line_cnt = 0;
- fclose(log_file);
- if ((log_file = fopen(tracefile,"w")) != NULL)
- {
- #ifdef _BSD
- setlinebuf(log_file);
- #else
- setvbuf(log_file,NULL,_IOLBF,0);
- #endif
-
- dolog("open_log file: %s\n",tracefile);
- }
- else
- log_limit = 0;
- }
- }
-
-
- va_start(args);
-
- fmt = va_arg(args, char *);
-
- if (!log_file)
- {
- return;
- }
-
- if (fmt && *fmt)
- {
- (void) vfprintf(log_file, fmt, args);
- #ifdef DEBUG
- if (debug)
- (void) vfprintf(stdout, fmt, args);
- #endif
- }
- va_end(args);
- }
-
- get_my_addr(myaddr)
- struct sockaddr_in *myaddr;
- {
- int n_interfaces, i;
- char *buf;
- struct ifconf ifc;
- struct ifreq *ifr;
- int s_in;
- /*
- unsigned long foo;
-
- bzero((caddr_t) myaddr,socksize(&ifr->ifr_addr));
- foo = inet_addr("132.236.91.204");
- bcopy((caddr_t) &foo, (caddr_t) &myaddr->sin_addr.s_addr, 4);
- return;
- */
-
-
- if ((s_in = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
- {
- my_perror("if_getlist: socket");
- exit(errno);
- }
-
- ifc.ifc_len = (MAXIF * sizeof (struct ifreq)) + sizeof(int);
-
- if ( !(buf = malloc(ifc.ifc_len)))
- {
- my_perror("if_getlist: malloc");
- exit(errno);
- }
-
- ifc.ifc_buf = buf;
-
- if (ioctl(s_in, SIOCGIFCONF, (caddr_t) &ifc) < 0)
- {
- my_perror("if_getlist: ioctl(SIOCGIFCONF)");
- exit(errno);
- }
-
- n_interfaces = ifc.ifc_len / sizeof (struct ifreq);
-
- ifr = (struct ifreq *) ifc.ifc_buf;
- for (i = 0; i < n_interfaces; i++)
- {
- if (ifr->ifr_addr.sa_family == AF_INET)
- {
- bcopy((caddr_t) &ifr->ifr_addr, (caddr_t) myaddr, socksize(&ifr->ifr_addr));
- break;
- }
- ifr = (struct ifreq *) ((caddr_t) ifr + (sizeof(*ifr) + socksize(&ifr->ifr_addr) - sizeof (ifr->ifr_addr)));
- }
- (void) free(buf);
- }
-
-
- int get_type(vidptr,csock)
- VideoPacketHeader *vidptr;
- struct sockaddr_in csock;
- {
- short cnt,*id;
-
-
- for (cnt=0; cnt<restrict_cnt; cnt++)
- if (restrict_list[cnt] == csock.sin_addr.s_addr)
- return(CLIENT);
-
- for (cnt=0; cnt<bcc_srv_cnt; cnt++)
- if (bcc_server_list[cnt] == csock.sin_addr.s_addr)
- return(BCC_SERVER);
-
- for (cnt=0; cnt<bcc_clt_cnt; cnt++)
- if (bcc_client_list[cnt] == csock.sin_addr.s_addr)
- return(BCC_CLIENT);
-
- for (cnt=0; cnt<ref_ucast_cnt; cnt++)
- if (ref_ucast_list[cnt] == csock.sin_addr.s_addr)
- return(REF3_SERVER);
-
- if (vidptr->message == kBCCOpen)
- {
- /*
- this must be a dynamic BCC client attempting to get a feed
- from us. If there is a conference ID for dynamic BCC clients,
- make sure his is correct, also check and see how many of
- these clients are already connected.
- */
-
- if (bcc_gclient_cnt == gbcc_cnt)
- return(-1);
-
- id = (short *) ((char *) vidptr + HEADERLEN);
-
- if ((gbcc_id != 0) && (gbcc_id != *id))
- return(-1);
-
- return(BCC_GCLIENT);
-
- }
-
- if (restrict_cnt != 0)
- return(-1);
-
- return(CLIENT);
- }
-
-
- short deny(csock)
- struct sockaddr_in csock;
- {
- short cnt;
-
- for (cnt=0; cnt<deny_cnt; cnt++)
- if (deny_list[cnt] == csock.sin_addr.s_addr)
- return(1);
-
- for (cnt=0; cnt<MAXCLIENT; cnt++)
- if (tmp_deny_list[cnt] == csock.sin_addr.s_addr)
- return(1);
-
- return(0);
- }
-
-
- tmp_deny(who,time)
- unsigned long who;
- int time;
-
- {
- struct in_addr in;
- short cnt;
-
- for (cnt=0; cnt<MAXCLIENT; cnt++)
- if (tmp_deny_list[cnt] == 0)
- break;
-
- if (tmp_deny_list[cnt] != 0)
- {
- in.s_addr = who;
- dolog("Unable to add %s to the temporary deny list\n",inet_ntoa(in));
- }
-
- tmp_deny_list[cnt] = who;
- tmp_deny_wait[cnt] = time;
- }
-